﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using LitJson;

[AddComponentMenu("PUEX/Affector/Lifetime/KillZone")]
public class PUEXKillZoneAffector : PUEXAffector {
	
	#region - Editable property
	public Vector3 zoneCenter;
	public string zoneCenterParamName = "";
	public Vector3 zoneSize;
	public string zoneSizeParamName = "";
	public bool inWorldSpace;
	#endregion
	
	#region - Property
	protected Bounds _bounds;
	#endregion
	
	#region - Lifecycle
	public PUEXKillZoneAffector ()
	{
		zoneCenter = Vector3.zero;
		zoneSize = new Vector3 (30f, 30f, 30f);
		inWorldSpace = true;
	}
	#endregion

	#region - Update
	public override void preUpdate (float dt)
	{
		base.preUpdate (dt);
		
		//!!! zone bounds is axis-align with emitter's setting
		Vector3 center = zoneCenter;
		Vector3 size = zoneSize;
		if (inWorldSpace) {
			if (ownerEmitter.keepLocal) {
				Matrix4x4 invMat = ownerEmitter.ownerParticleSystem.systemToWorldTransform.inverse;
				center = invMat.MultiplyPoint(center);
				Vector3 s = ownerEmitter.ownerParticleSystem.systemToWorldScale3;
				s = new Vector3 (1f / s.x, 1f / s.y, 1f / s.z);
				size.Scale(s);
			}
		} else {
			if (!ownerEmitter.keepLocal) {
				center = ownerEmitter.ownerParticleSystem.systemToWorldTransform.MultiplyPoint(center);
				size.Scale(ownerEmitter.ownerParticleSystem.systemToWorldScale3);
			}
		}
		_bounds = new Bounds (center, size);
	}

	public override void update (float dt, PUEXParticle particle)
	{
		if (!_bounds.Contains (particle.position))
			particle.kill ();
	}
	#endregion

	#region - Param property
	public override void updateParams (PUEXParticleSystem system)
	{
		Vector3 value;
		if (system.getParamVec3 (zoneCenterParamName, out value)) {
			zoneCenter = value;
		}
		if (system.getParamVec3 (zoneSizeParamName, out value)) {
			zoneSize = value;
		}
	}
	#endregion

	#region - Draw
	public void OnDrawGizmos()
	{
		if (!enabled)
			return;

		//NEEDFIX: zone bounds should axis-align with emitter's setting, but here axis-align with affector's setting
		Matrix4x4 defaultMatrix = Gizmos.matrix;
		Gizmos.matrix = Matrix4x4.identity;
		if (inWorldSpace) {
			Gizmos.matrix = Matrix4x4.identity;
		} else {
			Gizmos.matrix = transform.parent.transform.localToWorldMatrix;
		}
		
		Color defaultColor = Gizmos.color;
		Gizmos.color = Color.gray;

		Gizmos.DrawWireCube (zoneCenter, zoneSize);
		
		Gizmos.color = defaultColor;
		Gizmos.matrix = defaultMatrix;
	}
	#endregion

	#region - Serialization
	public override JsonData save (JsonData emitterData, JsonData systemData)
	{
		JsonData ret = base.save (emitterData, systemData);
		
		ret ["zone_center"] = PUEXUtils.serializeVector3 (zoneCenter);
		ret ["zone_center_param_name"] = zoneCenterParamName;
		ret ["zone_size"] = PUEXUtils.serializeVector3 (zoneSize);
		ret ["zone_size_param_name"] = zoneSizeParamName;
		ret ["in_world_space"] = inWorldSpace;
		
		return ret;
	}
	#endregion
	
}
